﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.Windows;
using System.Text.RegularExpressions;

namespace SimulacionExcelIne
{
    public class SimulacionHoja
    {
        public void Simulacion(Worksheet Hoja, float epsilon)
        {
  
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hojaEntrada"></param>
        static public void GenerarNumeroAleatorios(Worksheet hojaEntrada)
        {
            hojaEntrada.Range["B2",hojaEntrada.UsedRange.End[XlDirection.xlDown].Address.Replace("A","D")].Formula = "=ALEATORIO()";
            EstandarizacionHojaExcel.PintarAleatorios(hojaEntrada);
        }

        static public void GenerarTablaAleatoriaOrdenados(_Worksheet hojaEntrada)
        {
            hojaEntrada.Range["E2", "E2"].Formula = "=MIN(B2:D2)";
            hojaEntrada.Range["F2", "F2"].Formula = "=MEDIANA(B2:D2)";
            hojaEntrada.Range["G2", "G2"].Formula = "=MAX(B2:D2)";
            //Definimos el rango hasta donde se copiará la fórmula
            try
            {
                hojaEntrada.Range["E2", "G2"].AutoFill(hojaEntrada.Range["E2", hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address], XlAutoFillType.xlFillDefault);
            }
            catch
            {
            }           
        }

        internal static void GenerarFibradoTangente(Worksheet hojaEntrada, string Epsilon)
        {
            //Defenimos El Minimo
            string m = "MIN("+hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeConstants,1).Address.Replace("D","$A")+")";
            //Definimos el Maximo
            string M = "MAX(" + hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeConstants,1).Address.Replace("D", "$A") + ")";

            //Definimos el R1
            string R1 = "$E2";
            //Definimos el R2
            string R2 = "$F2";
            //Definimos el R3
            string R3 = "$G2";

            string x = "$A2";


                hojaEntrada.Range["H2", "H2"].Value = "=(((" + m + " - " + M + ")*(" + m + " - " + x + ") + (-POTENCIA(" + m + ";2) - 4*" + m + "*" + M +
                    "+ POTENCIA(" + M + ";2) + 6*" + m + "*" + x + " + 2*" + M + "*" + x + " - 4*POTENCIA(" + x + ";2))*" + Epsilon + ")*" + R1 + " + 8*(" + m +
                    " - " + x + ")*(" + M + " - " + x + ")*" + Epsilon + "*(" + R2 + ") +(-(" + M + "*" + x + ") + POTENCIA(" + m + ";2)*(-1 + " + Epsilon +
                    ") - (POTENCIA(" + M + ";2) - 6*" + M + "*" + x + " + 4*POTENCIA(" + x + ";2))*" + Epsilon + " + " + m + "*(" + M +
                    " + " + x + " - 4*" + M + "*" + Epsilon + " + 2*" + x + "*" + Epsilon + "))*(" + R3 +
                    "))/(POTENCIA(" + m + " - " + M + ";2)*((" + R1 + ") - (" + R3 + ")))";

            //Generar las 242 columnas con la fórmula
                //Primero hasta la última fila
            try
            {
                Range PrimeraColumnaSimulacion=hojaEntrada.Range["H2", hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address];
                hojaEntrada.Range["H2", "H2"].AutoFill(PrimeraColumnaSimulacion, XlAutoFillType.xlFillDefault);
                Range UltimaColumnaSimulacion = hojaEntrada.Range["H2",hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address.Replace("H","IO")];

                PrimeraColumnaSimulacion.AutoFill(UltimaColumnaSimulacion, XlAutoFillType.xlFillDefault);

            }
            catch
            {
            }
            
            for (int i = 0; i < 242; i++)
            {
                try
                {
                    hojaEntrada.get_Range(hojaEntrada.Cells[2, 8 + i], hojaEntrada.Cells[hojaEntrada.UsedRange.Rows.Count, 8 + i]).FormulaR1C1 =
                    hojaEntrada.get_Range(hojaEntrada.Cells[2, 8 + i], hojaEntrada.Cells[hojaEntrada.UsedRange.Rows.Count, 8 + i]).Value;
                    hojaEntrada.get_Range(hojaEntrada.Cells[2, 8 + i], hojaEntrada.Cells[hojaEntrada.UsedRange.Rows.Count, 8 + i]).Interior.ColorIndex = 20;
                }
                catch
                {
                    i--;
                }                
            }
        }

        private static void ObtenerCuadradoDeLosErrores(Worksheet hojaEntrada)
        {
            hojaEntrada.get_Range("IP1","IP1").Value = "Errores cuadráticos";
            hojaEntrada.get_Range("IP2", "IP2").Formula = "=POTENCIA(IJ2-A2;2)";
            hojaEntrada.get_Range("IP2", "IP2").AutoFill(hojaEntrada.Range["IP2", hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)], XlAutoFillType.xlFillDefault);
        }

        private static void ObtenerValorEstimado(Worksheet hojaEntrada, string Epsilon)
        {
            string media = "IK2";

            //Defenimos El Minimo
            string m = "MIN("+((Range)hojaEntrada.Columns["A",Missing.Value]).SpecialCells(XlCellType.xlCellTypeConstants,1).Address+")";
            //Definimos el Maximo
            string M = "MAX(" + ((Range)hojaEntrada.Columns["A", Missing.Value]).SpecialCells(XlCellType.xlCellTypeConstants, 1).Address + ")";
            string Estimado = "(-" + M + "*" + Epsilon + " + " + m + "*(1 - " + Epsilon + ") + (-" + m + " + " + M + ")*" + media + ")/(1 - 2*" + Epsilon + ")";

            hojaEntrada.get_Range("IJ1", "IJ1").Value = "Valor estimado";
            hojaEntrada.Range["IJ2", "IJ2"].Formula = "=" + Estimado;
            hojaEntrada.Range["IJ2", "IJ2"].AutoFill(hojaEntrada.Range["IJ2", hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address.Replace("O", "J")],XlAutoFillType.xlFillDefault);
        }

        internal static void GenerarInforme(Worksheet hojaEntrada, string Epsilon)
        {            
            //Finalmente calcular la media y desviación estandar

            //Promedio
            hojaEntrada.get_Range(hojaEntrada.Cells[1, 245], hojaEntrada.Cells[1, 245]).Value = "promedio";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.Cells[2, 245]).Formula = "=PROMEDIO(B2:II2)";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.Cells[2, 245]).AutoFill(hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address), XlAutoFillType.xlFillDefault);
            //Fijar los valores
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).FormulaR1C1 =
                hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).Value;
            //Desviacion estandar muestral
            hojaEntrada.get_Range(hojaEntrada.Cells[1, 246], hojaEntrada.Cells[1, 246]).Value = "Desviación estandar";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 246], hojaEntrada.Cells[2, 246]).Formula = "=DESVEST(B2:II2)";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 246], hojaEntrada.Cells[2, 246]).AutoFill(hojaEntrada.get_Range(hojaEntrada.Cells[2, 246], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address), XlAutoFillType.xlFillDefault);
            //Fijar los valores
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 246], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).FormulaR1C1 =
                hojaEntrada.get_Range(hojaEntrada.Cells[2, 246], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).Value;

            //Punto De apertura menor
            hojaEntrada.get_Range(hojaEntrada.Cells[1, 247], hojaEntrada.Cells[1, 247]).Value = "Límite inferior";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 247], hojaEntrada.Cells[2, 247]).Formula = "=IK2-IL2";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 247], hojaEntrada.Cells[2, 247]).AutoFill(hojaEntrada.get_Range(hojaEntrada.Cells[2, 247], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address), XlAutoFillType.xlFillDefault);

            //Promedio
            hojaEntrada.get_Range(hojaEntrada.Cells[1, 248], hojaEntrada.Cells[1, 248]).Value = "promedio";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 248], hojaEntrada.Cells[2, 248]).Formula = "=PROMEDIO(B2:II2)";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 248], hojaEntrada.Cells[2, 248]).AutoFill(hojaEntrada.get_Range(hojaEntrada.Cells[2, 248], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address), XlAutoFillType.xlFillDefault);

            //Fijar los valores
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).FormulaR1C1 =
                hojaEntrada.get_Range(hojaEntrada.Cells[2, 245], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)).Value;

            //Punto De apertura menor
            hojaEntrada.get_Range(hojaEntrada.Cells[1, 249], hojaEntrada.Cells[1, 249]).Value = "Límite Superior";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 249], hojaEntrada.Cells[2, 249]).Formula = "=IK2+IL2";
            hojaEntrada.get_Range(hojaEntrada.Cells[2, 249], hojaEntrada.Cells[2, 249]).AutoFill(hojaEntrada.get_Range(hojaEntrada.Cells[2, 249], hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address), XlAutoFillType.xlFillDefault);

            ObtenerValorEstimado(hojaEntrada, Epsilon);
            ObtenerCuadradoDeLosErrores(hojaEntrada);
        }

        /// <summary>
        /// Dado la terna de numeros aleatorios de distribución unforme y su terna ordenada, elimina toda la columna
        /// ya que no es necesaria.
        /// </summary>
        /// <param name="hojaEntrada">Workshhet</param>
        internal static void EliminarNumerosAleatorios(Worksheet hojaEntrada)
        {
            //Eliminar los numeros aleatorios
            hojaEntrada.Range["B1", hojaEntrada.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address.Replace("IO", "G")].Delete(XlDirection.xlToLeft);

        }

        internal static void CalculoPesosEspecificos(Worksheet i)
        {

            //***Primersa celda variable la cual se calcularan los pesos***//
            string primeraCeldaColumna2 = "B2";

            //***Información:= dirección de la ultima celda***//
            string ultimaCelda = i.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell).Address;

            //***Información:= ultima celda de la segunda columna


            //***Información:= cantidad de filas usadas
            int numeroDeFilasEnTexto= i.UsedRange.Rows.Count;
            int numeroDeColumnasEnTexto = i.UsedRange.Columns.Count;


            //***Informacion:= primera celda en donde colocar la fórmula

            string primeraCeldaFormula = i.Range[i.Cells[numeroDeFilasEnTexto + 5, 2], i.Cells[numeroDeFilasEnTexto + 5, 2]].Address;


            //***Informacion:= dirección de la ultima celda a la cual se le va a aplicar la formula
            string ultimaCeldaFormula = i.Range[i.Cells[2 * numeroDeFilasEnTexto + 4, 2], i.Cells[2 * numeroDeFilasEnTexto + 5, 2]].Address;


            //Objetivo:= la idea es colocar en la segunda columna 5 celdas más abajo de la ultima celda usada la siguiente
            //fórmula

            string FormulaPonderadores = primeraCeldaColumna2 + "/SUMA(B2:B" + numeroDeFilasEnTexto.ToString() + ")";

            //Objetivo:=Fijar las filas en el denominador, lo haremos mediante expresiones regulares

            FormulaPonderadores = FormulaPonderadores.Replace("B", "B$");

            //***Objetivo:= Arrastramos la fórmula por todas las filas
            //Objetivo:=Fijar las filas en el denominador, lo haremos mediante expresiones regulares

            FormulaPonderadores = FormulaPonderadores.Replace("B", "B$");

            //***Objetivo:= Escribir en primera celda la fórmula requerida

            i.Range[primeraCeldaFormula, primeraCeldaFormula].Formula = FormulaPonderadores;

            //***Objetivo:= Arrastramos la fórmula por todas las filas
            }
    }
}
